home *** CD-ROM | disk | FTP | other *** search
- // hi there
-
- // Copyright © 1997 Pierre Houston. All rights reserved.
- // or something like that
-
- // Portions copied from RandomFinderStrings, Mike Scanlin. 24 Jan 1993
-
- #ifndef __TYPES__
- # include <Types.h>
- #endif
-
- #ifndef __QUICKDRAW__
- # include <Quickdraw.h>
- #endif
-
- #ifndef __OSUTILS__
- # include <OSUtils.h>
- #endif
-
- #ifndef __WINDOWS__
- # include <Windows.h>
- #endif
-
- #ifndef __MEMORY__
- # include <Memory.h>
- #endif
-
- #ifndef __LOWMEM__
- # include <LowMem.h>
- #endif
-
- #include "ShowInitIcon.h"
-
-
- #define rLoadBadIcon 128
- #define rLoadOKIcon1 129
- #define rLoadOKIcon2 130
- #define rLoadOKIcon3 131
- #define rLoadOKIcon4 132
- #define rLoadOKIcon5 133
- #define rLoadOKIcon6 134
- #define rLoadOKIcon7 135
-
- typedef pascal void (*ScrollRectProcPtr)(const Rect *r, short dh, short dv, RgnHandle rgn);
- struct PatchGlobals {
- ScrollRectProcPtr oldScrollRect;
- RgnHandle savedClipRgn;
- RgnHandle tempRgn;
- unsigned long flags;
- };
- typedef struct PatchGlobals PatchGlobals, *PatchGlobalsPtr;
-
- #define HACKOFF 1
- #define HACKMOREOFTEN 2
- #define INVERTHACKRECTS 3
-
- pascal void MyScrollRect(const Rect *r, short dh, short dv, RgnHandle rgn);
- void FibonacciScrollMagic(short a, short b, short sum, short count, Boolean up, const Rect *r, GrafPtr pPort);
- void StartPatchCode(void);
- void EndPatchCode(void);
-
- pascal void main()
- {
- // anyone know how to make a fat patch??
-
- Ptr patchPtr;
- PatchGlobalsPtr pgPtr;
- long codeSize, offset;
- long time;
-
- /* try and get some memory in the system heap
- * for code and globals */
- codeSize = (long) EndPatchCode - (long) StartPatchCode;
- patchPtr = NewPtrSys(codeSize + sizeof(PatchGlobals));
- if (!patchPtr)
- return; /* out of memory--abort patching */
-
- /* initialize the patch globals at the
- * beginning of the block */
- pgPtr = (PatchGlobalsPtr) patchPtr;
- pgPtr->oldScrollRect = (ScrollRectProcPtr) NGetTrapAddress(_ScrollRect, ToolTrap);
-
- // alloc a region first time we hit our patch
- pgPtr->savedClipRgn = 0L;
- pgPtr->tempRgn = 0L;
- pgPtr->flags = 0;
-
- /* move the code into place after the globals */
- BlockMove(StartPatchCode, patchPtr + sizeof(PatchGlobals), codeSize);
-
- /* set the patches */
- patchPtr += sizeof(PatchGlobals);
- offset = (long) MyScrollRect - (long) StartPatchCode;
- NSetTrapAddress((UniversalProcPtr) (patchPtr + offset), _ScrollRect, ToolTrap);
-
- // call ShowInitIcon
- ShowInitIcon(rLoadOKIcon1, false);
- Delay(26, &time);
- ShowInitIcon(rLoadOKIcon2, false);
- Delay(12, &time);
- ShowInitIcon(rLoadOKIcon3, false);
- Delay(12, &time);
- ShowInitIcon(rLoadOKIcon4, false);
- Delay(15, &time);
- ShowInitIcon(rLoadOKIcon5, false);
- Delay(18, &time);
- ShowInitIcon(rLoadOKIcon6, false);
- Delay(20, &time);
- ShowInitIcon(rLoadOKIcon7, true);
-
- {
- Str255 str;
- KeyMap keys;
- GetKeys(keys);
- if (keys[1] & 0x8)
- {
- pgPtr->flags |= HACKOFF; // turn hack off
- NumToString((long) &pgPtr->flags, &str[5]);
- *(unsigned long*) &str[1] = ';dl '; // prepend ';dl ' to string
- str[0] = str[5] + 5;
- str[5] = '#';
- DebugStr(str);
- }
- }
- }
-
-
- void StartPatchCode()
- {
- }
-
- pascal void MyScrollRect(const Rect *r, short dh, short dv, RgnHandle rgn)
- {
- PatchGlobalsPtr pgPtr;
- GrafPtr pPort;
- short scrollDistance;
- short fontHeight;
- ControlHandle windowControl;
- int windowControlDistance;
- Boolean doAnim = false;
- Rect tempRect;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- if (!(pgPtr->flags & HACKOFF))
- {
- GetPort(&pPort);
- fontHeight = 16; // %%% HACK! :-)
- scrollDistance = dv < 0 ? -dv : dv;
-
- // how do we tell its a document paging down?
- // if the port is the frontmost window and rect is about the size of a vertical scrollbar
- // in the window and its scrolling vertically more than a couple lines of text, and less
- // than almost the entire height
-
- if (!dh && pPort == FrontWindow()
- && scrollDistance <= r->bottom - r->top - fontHeight
- && (pgPtr->flags & HACKMOREOFTEN || scrollDistance >= fontHeight * 3))
- {
- #if 0
- // look for a vertical scrollbar in the window
- // if we don't do this, then maybe the app, for example, is scrolling down a portion of
- // the visible document while its inserting another line
-
- windowControl = ((WindowPeek) pPort)->controlList;
- while (windowControl)
- {
- // if correct width and at least the minimum height, it might be a scroll bar
- if (tempRect.right - tempRect.left == 16 && tempRect.bottom - tempRect.top >= 48)
- {
- // if control is nearly right beside the scroll rect, lets just say it probably is
- // a scroll bar and we'll do the scrolling animation (woohoo)
- tempRect = (**windowControl).contrlRect;
- windowControlDistance = tempRect.left - r->right;
- if ((windowControlDistance < 0 ? -windowControlDistance : windowControlDistance) < 3)
- {
- doAnim = true;
- break;
- }
- }
- windowControl = (**windowControl).nextControl;
- }
-
- if (!doAnim) SysBeep(10);
- #else
- doAnim = true;
- #endif
- }
- }
-
- if (doAnim)
- {
- // do the animation
- FibonacciScrollMagic(0, 1, 1, scrollDistance, dv < 0, r, pPort);
-
- // clip out the destination rect so the real ScrollRect doesn't scroll it again
- if (!pgPtr->savedClipRgn)
- pgPtr->savedClipRgn = NewRgn();
- if (!pgPtr->tempRgn)
- pgPtr->tempRgn = NewRgn();
- CopyRgn(pPort->clipRgn, pgPtr->savedClipRgn);
- RectRgn(pgPtr->tempRgn, r);
- OffsetRgn(pgPtr->tempRgn, 0, dv);
- DiffRgn(pPort->clipRgn, pgPtr->tempRgn, pPort->clipRgn);
-
- if (pgPtr->flags & INVERTHACKRECTS)
- {
- long time;
-
- InvertRect(&tempRect);
- Delay(30, &time);
- InvertRect(&tempRect);
-
- InvertRgn(pPort->clipRgn);
- Delay(30, &time);
- InvertRgn(pPort->clipRgn);
- }
-
- /* call the real ScrollRect */
- (*pgPtr->oldScrollRect)(r, dh, dv, rgn);
-
- // restore the clip region
- CopyRgn(pgPtr->savedClipRgn, pPort->clipRgn);
- }
- else
- {
- /* call the real ScrollRect */
- (*pgPtr->oldScrollRect)(r, dh, dv, rgn);
- }
- }
-
- void FibonacciScrollMagic(short a, short b, short sum, short count, Boolean up, const Rect *r, GrafPtr pPort)
- {
- if (sum + a + b >= count)
- {
- // the next recursion would be too far, so exit the recursion and start scrolling
- // scroll by b pixels plus the remainder
- // (scrolling only b pixels & returning will end up scrolling an offset equal to sum
- // so the remainder is the amount that would be left over: count - sum)
- b += count - sum;
- sum = count;
- }
- else
- {
- // we will scroll b pixels
- // do the scroll for this iteration last, so the largest amount is scrolled first
- FibonacciScrollMagic(b, a + b, sum + a + b, count, up, r, pPort);
- }
-
- // begin another block here so the compiler can guess not to leave stack space for these
- // local vars during all that recursion above. if we do leave this stack space before the
- // recursion, then theres space left at every iteration. waste stack not or want stack not.
-
- {
- // pick the pixels to scroll this iteration
- // we also have to erase the pixels that are left behind
- // sum is the number of pixels this and earlier iterations will scroll in total
- // so the offset that has already been scrolled should be count - sum
- // use this info do we don't have to scroll pixels already erased in past iterations
- Rect rDst;
- Rect rSrc = *r;
- Rect rWake; // ie. the pixels in our wake
- if (up)
- {
- rSrc.top += b; // pixels up here would get copied up out of portRect
- rSrc.bottom -= count - sum; // pixels down here have already been erased
-
- rDst = rSrc;
- OffsetRect(&rDst, 0, -b); // negative value to offset coordinates up
-
- rWake = rSrc;
- rWake.top = rDst.bottom; // erase the pixels that won't get copied over
- }
- else
- {
- rSrc.top += count - sum; // pixels up here have already been erased
- rSrc.bottom -= b; // pixels down here would get copied down out of portRect
-
- rDst = rSrc;
- OffsetRect(&rDst, 0, b); // positive value to offset coordinates down
-
- rWake = rSrc;
- rWake.bottom = rDst.top; // erase the pixels that won't get copied over
- }
-
- CopyBits(&pPort->portBits, &pPort->portBits, &rSrc, &rDst, srcCopy, NULL);
- EraseRect(&rWake);
-
- #if 0
- if (!a)
- {
- long time;
- /*InvertRect(&rSrc);
- Delay(6, &time);
- InvertRect(&rSrc);
- Delay(15, &time);*/
- InvertRect(&rDst);
- Delay(6, &time);
- InvertRect(&rDst);
- /*Delay(15, &time);
- InvertRect(&rWake);
- Delay(6, &time);
- InvertRect(&rWake);*/
- Delay(20, &time);
- }
- #endif
-
- // if this happens to be the first iteration, we will never scroll a pixels
- // thats why the caller should call the first iteration with a=0, b=1
- }
- }
-
- void EndPatchCode()
- {
- }
-
-